﻿
Imports std

Public Class processorHttpServer
    Inherits httpServer2
    Public Shadows Event reject(ByVal context As httpContext)
    Public Shadows Event receive(ByVal context As httpContext)

    Protected _processors As vector(Of requestProcessor) = Nothing

    Public Function processors() As vector(Of requestProcessor)
        assert(Not _processors Is Nothing, "_processors is nothing.")
        Return _processors
    End Function

    Public Sub insertRequestProcessor(ByVal processor As requestProcessor)
        insertRequestProcessor(processor, Nothing)
    End Sub

    Public Sub insertRequestProcessor(ByVal processor As requestProcessor, ByVal config As configParser)
        If Not processor Is Nothing Then
            processors().push_back(processor)
            raiseError("enable requestProcessor " + processor.GetType.FullName())
            processor.initial(config)
        End If
    End Sub

    Public Sub addRequestProcessor(ByVal processor As requestProcessor)
        insertRequestProcessor(processor)
    End Sub

    Public Sub addRequestProcessor(ByVal processor As requestProcessor, ByVal config As configParser)
        insertRequestProcessor(processor, config)
    End Sub

    Private Sub processorHttpServer_reject(ByVal context As httpContext) Handles MyBase.reject
        Try
            If Not errorpage.processErrorPage(context) Then
                raiseError("errorpage returns false to request, request " + context.url().full() _
                            , errorHandle.errorType.exclamation)
            End If
        Catch ex As Exception
            raiseError("caught exception in errorpage.processErrorPage, " + GetType(errorpage).FullName + _
                       ", " + context.url().full + ", " + ex.Message + ", " + ex.StackTrace, _
                       errorHandle.errorType.warning)
        End Try
    End Sub

    Private Sub processorHttpServer_receive(ByVal context As httpContext) Handles MyBase.receive
        assert(Not context Is Nothing, "context is nothing.")

        Dim i As Int64
        For i = 0 To processors().size() - 1
            assert(Not processors()(i) Is Nothing, "processors()(" + Convert.ToString(i) + ") is nothing.")
            Dim path As String = Nothing
            'attention, pathidentity() should be called only once in a context / request.
            'especially to calculate the length, i cannot confirm it will always be a constance
            path = processors(i).pathidentity()
            If strsame(context.url.pathquery, path, strlen(path), False) Then
                Try
                    If Not processors()(i).process(context) Then
                        raiseError("processor returns false to request. processor " + _
                                   processors()(i).GetType().FullName() + ", request " + context.url().full(), _
                                   errorHandle.errorType.warning)
                        i = processors().size() + 1
                    End If
                Catch ex As Exception
                    raiseError("caught exception in processor.process, " + processors()(i).GetType().FullName() + _
                               ", " + context.url().full + ", " + ex.Message + ", " + ex.StackTrace, _
                               errorHandle.errorType.critical)
                End Try
                Exit For
            End If
        Next

        If i >= processors.size() Then
            If i = processors().size() _
                AndAlso Not strsame(context.url.path, strlen(context.url.path) - strlen(network.pathSeperator) _
                                    , network.pathSeperator, 0, strlen(network.pathSeperator)) Then
                context.response.Redirect(network.pathSeperator)
            Else
                If Not errorpage.processErrorPage(context) Then
                    raiseError("errorpage returns false to request, request " + context.url().full() _
                                , errorHandle.errorType.exclamation)
                End If
            End If
        End If
    End Sub

    Private Sub processorHttpServer_reject1(ByVal context As httpContext) Handles Me.reject
        debugassert(False, "should not call processorHttpServer.reject.")
    End Sub

    Private Sub processorHttpServer_receive1(ByVal context As httpContext) Handles Me.receive
        debugassert(False, "should not call processorHttpServer.receive.")
    End Sub

    Public Overrides Sub [stop]()
        Dim i As Int64
        If Not _processors Is Nothing Then
            For i = 0 To processors.size() - 1
                processors()(i).close()
            Next
            processors().clear()
        End If
        MyBase.[stop]()
    End Sub

    Public Sub New(Optional ByVal para As httpContext.parameterDefinition = Nothing)
        MyBase.New(para)
        _processors = New vector(Of requestProcessor)()
    End Sub
End Class
